
#include<unistd.h>
#include<iostream>
#include<sys/types.h>
#include<sys/wait.h>
#include<sys/eventfd.h>
#include <pthread.h>
using namespace std;

//eventfd不同模式
int main()
{
    //模式1：EFD_NONBLOCK | EFD_CLOEXEC
    int efd = ::eventfd(0,EFD_NONBLOCK | EFD_CLOEXEC | EFD_SEMAPHORE);
    //模式2：

    if(efd == -1)
    {
        perror("event fd!");
        return 1;
    }

    uint64_t value;
    //写入1
    value = 1;
    ::write(efd,&value,sizeof(value));
    printf("Wrote 1 to eventfd\n");

    //写入2
    value = 2;
    ::write(efd,&value,sizeof(value));
    printf("Wrote 2 to eventfd\n");

    value = 0;//防止干扰，先将value直接清空
    //读取一次(计数器-1)
    read(efd,&value,sizeof(value));
    printf("Read value:%llu (counter is now 2)\n",(unsigned long long)value);
    
    value = 0;//防止干扰，先将value直接清空
    //再读取一次(计数器-1)
    read(efd,&value,sizeof(value));
    printf("Read value:%llu (counter is now 1)\n",(unsigned long long)value);
    
    value = 0;//防止干扰，先将value直接清空
    //读取一次(计数器-1)
    read(efd,&value,sizeof(value));
    printf("Read value:%llu (counter is now 0)\n",(unsigned long long)value);
    
    value = 0;//防止干扰，先将value直接清空
    //读取一次(计数器-1)
    read(efd,&value,sizeof(value));
    printf("Read value:%llu (counter is now 0)\n",(unsigned long long)value);

    //关闭eventfd 
    close(efd);
    return 0;
}











// //线程间事件通知
// void* worker(void* arg)
// {
//    int efd = *(int*)arg;
//    uint64_t value;
//    while(true)
//    {
//      read(efd,&value,sizeof(value));//从eventfd中读取事件
//      cout << "work thread val: " << value ;
//      printf("worker thread received event\n");
//    }
//    return NULL;
// }


// int main()
// {
//     int efd = ::eventfd(0,EFD_CLOEXEC); //创建eventfd
//     if(efd == -1) 
//     {
//         perror("eventfd");
//         return 1;
//     }
//    //创建工作线程
//     pthread_t thread;
//     pthread_create(&thread,NULL,worker,&efd);
   
//     //向eventfd写入事件
//     uint64_t value = 0;
//     while(value < 2)
//     {
//         cout << "main value:" << value;
//         write(efd,&value,sizeof(value));
//         value++;
//         sleep(1);
//         printf("main thread sent value\n");
//     }
//     pthread_cancel(thread);
//     pthread_join(thread,NULL);
//     close(efd);
//     return 0;
// }







// //进程间事件通知
// int main()
// {
//    //1.创建eventfd
//    int efd = ::eventfd(0,EFD_CLOEXEC);
//    if(efd == -1)
//    {
//       perror("eventfd");
//       return 1;
//    }
//    //创建子进程
//    pid_t pid  = fork();
//    if(pid == -1)
//    {
//       perror("fork");
//       return 2;
//    }

//    if(pid == 0)
//    {
//        uint64_t value;
//        read(efd,&value,sizeof(value)); //从eventfd中读取事件
//        cout << value << endl;
//        printf("child process received event\n");
//        close(efd);
//        return 0;
//    }
//    else 
//    {
//       uint64_t value = 2;
//       write(efd,&value,sizeof(value)); //向eventfd中写入事件
//       printf("Parent process sent event!\n");
//       ::wait(NULL);//等待子进程结束
//       close(efd);
//    }


//     return 0;
// }
